package com.eden.api.security;

import com.eden.api.security.annotation.AnonymousAccess;
import com.eden.api.security.service.ITokenService;
import com.eden.common.exception.api.ApiException;
import com.eden.common.utils.ServletUtils;

import java.lang.reflect.Method;

/**
 * @program: eden
 * @description: ${description}
 * @author: Mr.Jiao
 * @create: 2020-09-14 17:47
 */

public class JwtUser {

    private JwtUser(){}

    private static class SingletonServletUser {
        private static final JwtUser instance = new JwtUser();
    }

    public static JwtUser getInstance() {
        return SingletonServletUser.instance;
    }

    private ITokenService tokenService;
    private static ThreadLocal<Method> targetMethod = new ThreadLocal<>();
    private static ThreadLocal<Class> targetClass = new ThreadLocal<>();

    /**
     * @description: 检查是否被@AnonymousAccess修饰
     * @date: 2019/11/16 13:44
     * @author: wenqing
     * @param
     * @return: void
     * @throws:
     */
    private void checkMethodCanBeCalled() {

        String currentClassName = Thread.currentThread().getStackTrace()[3].getClassName();
        String currentMethodName = Thread.currentThread().getStackTrace()[3].getMethodName();
        if(targetClass.get() == null) return;
        String targetClassName = targetClass.get().getName();
        String targetMethodName = targetMethod.get().getName();
        if(targetMethod.get().isAnnotationPresent(AnonymousAccess.class)) {
            throw new ApiException("方法"+targetClassName+"."+targetMethodName+"被注解@AnonymousAccess修饰，不能调用"+currentClassName+"."+currentMethodName+"方法。");
        }
    }

    /**
     * @description: 仅限于经AuthenticationInterceptor拦截过的controller使用，即方法被@AnonymousAccess修饰则不能调用
     * @date: 2019/11/4 17:59
     * @author: wenqing
     * @param
     * @return: com.nantian.api.security.LoginUser {@link com.eden.api.security.LoginUser}
     * @throws:
     */
    public LoginUser getLoginUser() {
        checkMethodCanBeCalled();
        return tokenService.getLoginUser(ServletUtils.getRequest());
    }

    /**
     * @description: 仅限于经AuthenticationInterceptor拦截过的controller使用，即方法被@AnonymousAccess修饰则不能调用
     * @date: 2019/11/4 17:58
     * @author: wenqing
     * @param
     * @return: java.lang.Long
     * @throws:
     */
    public Long getUserId() {
        return getLoginUser().getUser().getUserId();
    }

    /**
     * @description: 仅限于经AuthenticationInterceptor拦截过的controller使用，即方法被@AnonymousAccess修饰则不能调用
     * @date: 2019/11/4 17:58
     * @author: wenqing
     * @param
     * @return: java.lang.String
     * @throws:
     */
    public String getLoginName() {
        checkMethodCanBeCalled();
        return getLoginUser().getUser().getLoginName();
    }
}
